\documentclass{report}
\usepackage{graphicx}     
\usepackage{hyperref}
\usepackage{unicode}
\usepackage[utf8x]{inputenc}
\begin{document}

\title{Progetto Tecnologie dei Servizi 1: Torrent Dam}
\author{Valerio Ponte}
\date{}
\maketitle

\tableofcontents
\chapter{Introduzione}
Il seguente documento accompagna il progetto svolto per il corso di Tecnologie dei Servizi 1. Il progetto è consistito nel progettare e sviluppare un servizio web, di cui successivamente è stato effettuato il deployement su piattaforma cloud. Nel presente documento verrà presentato quali sono state le decisioni progettuali nello sviluppo (capitolo \ref{ch:design}) e come effettuare l'installazione dell'applicazione (capitolo \ref{ch:inst}).

Il servizio, denominato Torrent Dam, permette agli utenti, previa registrazione, di utilizzare un client torrent remotamente. Una volta registrato infatti, un utente ha accesso ad un interfaccia web che gli permette di effettuare l'upload di un file di metadati (file .torrent) e così avviare il processo di scaricamento dei file relativi ad esso. Quando il download sarà completato, l'utente potrà scaricare i dati attraverso una normale HTTP Get.

I possibili casi d'uso individuati comprendono, ad esempio:
\begin{itemize}
	\item utente limitato dal dispositivo, ovvero che non ha la possibilità di installare un client torrent sul proprio dispositivo (ad es. pda, smartphone); il servizio ha un interfaccia REST e pertanto è sufficiente un semplice browser web per accedere alle funzionalità di un client torrent.
	\item utente limitato dalla rete, ovvero la cui connessione ad internet è limitata (ad es. protetta da un firewall con solo determinate porte aperte, o con dei limiti sul download/upload mensili); oltre al motivo precedente, il trasferimento di dati richiesto per effettuare il download dei dati relativi ad un file torrent è limitato al solo upload del file di metadati (file .torrent), e successivamente al download dei dati scaricati dal servizio. Tutta la parte di scambio dati relativa al download dalla rete peer-2-peer è gestita dal servizio stesso.
	\item utente che non ha la possibilità di rimanere connesso ad internet per lunghi periodi; è ovvio che utilizzando Torrent Dam un utente non deve lasciare il proprio dispositivo attivo e connesso ad internet, pertanto è sufficiente che inizi il download e successivamente si ricolleghi al servizio per scaricare i dati completati.
\end{itemize}

\chapter{Design}
\label{ch:design}
In questo capitolo, viene descritto in maniera approfondita quali sono state le scelte di sviluppo e il funzionamento dell'applicazione. 

\section{Registrazione}
Innanzi tutto, l'applicazione è accessibile solo previa registrazione. Questa scelta deriva dal fatto che non è stato ritenuto necessario e opportuno esporre alcun componente ad utenti non registrati. D'altro canto, la registrazione (figura \ref{fig:signup}) richiede il minimo di dati necessari ad identificare un utente: un indirizzo email valido, password, nome e cognome.

La registrazione fallisce nel caso in cui l'email inserita non sia corretta o sia già presente nel database dell'applicazione (i.e. utente già registrato con quell'indirizzo email), la password digitata sia diversa dalla conferma o uno qualsiasi dei campi sia vuoto. Non ci sono particolari processi di validazioni del nome e del cognome dell'utente, dato che questi vengono usati unicamente come nome utente all'interno dell'applicazione. 

Se tutti i criteri sono rispettati, la registrazione va a buon fine, viene creata una nuova directory per i futuri download dell'utente nello storage dell'applicazione e l'utente viene aggiunto al database; all'interno del database della password inserita è memorizzato l'hash MD5 e non la versione in chiaro, per ovvie ragioni di sicurezza. 

 \begin{figure}
\centering
\caption{Schermata di registrazione di un utente.}
\label{fig:signup}
\includegraphics[width = 0.9\textwidth]{../figures/signup.png}
\end{figure} 

\section{Gestione Torrent}

\begin{figure}
\centering
\caption{Schermata principale di un utente.}
\label{fig:home}
\includegraphics[width = 0.9\textwidth]{../figures/home.png}
\end{figure}   

Una volta registrato e dopo aver effettuato il login, un utente viene mandato nella sua pagina principale (figura \ref{fig:home}). Come si può vedere dalla figura, dalla barra di navigazione in cima alla pagina si possono effettuare le seguenti scelte:
\begin{description}
	\item[logout] viene terminata la sessione all'interno dell'applicazione e l'utente viene mandato alla pagina iniziale (i.e. pagina di login);
	\item[manage your torrent dam account] tramite questa opzione l'utente ha la possibilità di modificare i suoi dati personali; questa parte dell'applicazione verrà spiegata con maggior dettaglio in seguito;
	\item[home] ritorna alla pagina iniziale (in questo caso, questa pagina).
\end{description}

La barra di navigazione è persistente, nel senso che rimane invariata indipendentemente dalla pagina che sta visitando un utente.

Inoltre, un utente ha la possibilità di aggiungere un nuovo file di metadati premendo sul bottone \textit{Add torrent}, che lo porta alla schermata in figura \ref{fig:add_torrent}. Una volta aggiunto un nuovo file, accade uno dei seguenti eventi:

\begin{figure}
\centering
\caption{Schermata per l'aggiunta di un nuovo file di metadati.}
\label{fig:add_torrent}
\includegraphics[width = 0.9\textwidth]{../figures/add_torrent.png}
\end{figure}    

\begin{itemize}
	\item torrent non esistente: l'utente è il primo che effettua l'upload di quel particolare file di metadati, questo viene aggiunto alla tabella dei torrent, il download viene iniziato dal client torrent installato sul server (Transmission) e viene aggiunta nella tabella torrent\_users la relazione tra l'utente e il nuovo file torrent. Dopodiché l'utente viene rimandato alla sua home page.
	\item torrent esistente: il torrent è già presente nella tabella dei torrent. Questo può accadere, ad esempio, perché qualche altro utente dell'applicazione ha iniziato precedentemente il download del torrent in questione. Se questo è il caso, ovviamente non viene creata una nuova tupla nella tabella dei torrent, ma viene solo aggiunta la nuova relazione tra l'utente corrente e il torrent nella tabella torrent\_users. Dopodiché l'utente viene mandato alla home page. 
\end{itemize}

Come si sarà ormai intuito, la relazione tra torrent e utenti è molti a molti. Ogni utente può essere associato a zero o più torrent, ed ogni torrent è associato ad almeno un utente ma potenzialmente ad un numero maggiore. L'adozione di questa scelta deriva dal fatto che in questo modo il servizio agisce anche da \textit{cache} per i torrent: il primo utente che decide di scaricare un particolare file torrent dovrà attendere che il servizio lo scarichi, mentre tutti i successivi utenti potranno scaricarlo non appena il download di questo sarà terminato, attraverso una semplice HTTP Get.

Al momento non sono previsti limiti massimi di residenza nello storage dei dati relativi ad un file di metadati, però, nel caso questo non sia più associato a nessun utente, esso viene rimosso assieme ai suoi dati, liberando spazio sullo storage. La rimozione è un processo molto semplice: come si vede in figura \ref{fig:tor_list}, un volta caricati i file di metadati un utente ha una lista di torrent in download o già scaricati; nel caso voglia eliminarne uno è sufficiente che prema sul bottone \textit{delete}. Questo ha i seguenti effetti:

\begin{itemize}
	\item Rimozione della relazione nel database tra l'utente e il torrent;
	\item nel caso questo fosse l'ultimo utente associato con il torrent, rimozione del file di metadati, dei dati relativi ad esso e rimozione della tupla relativa al torrent nel database;
\end{itemize}

Quando il download ``lato server'' è terminato (i.e. la percentuale riportata accanto al torrent è 1), comparirà il bottone \textit{retrieve} attraverso il quale un utente potrà scaricare un file .zip contentente i dati relativi al torrent attraverso una normale HTTP Get servita dal webserver. 

\begin{figure}
\centering
\caption{Schermata principale di un utente dopo l'aggiunta di un file torrent.}
\label{fig:tor_list}
\includegraphics[width = 0.9\textwidth]{../figures/tor_list.png}
\end{figure} 

\section{Gestione Account}
Premendo sul link \textit{manage your torrent dam account}, un utente che ha effettuato il login accede ad una pagina attraverso la quale può modificare i suoi dati personali che aveva inserito in fase di registrazione. Naturalmente i dati inseriti, come in fase di registrazione, vengono validati prima di essere accettati.

Esiste inoltre una categoria di utenti speciali, detti \textit{admin}. Questi hanno accesso alla parte di amministrazione del sito. Da qui possono gestire le risorse del sito, ovvero i torrent e gli utenti. Su un utente un amministratore può effettuare le seguenti operazioni:
\begin{description}
	\item[delete] Rimuovere un utente, e tutte le sue associazioni con i torrent. Nel caso rimangano dei torrent senza associazione con nessun altro utente, vengono rimossi anch'essi.
	\item[add] Creare un nuovo utente.
	\item[manage torrents] Aggiungere e/o rimuovere torrent relativi ad un utente.
\end{description}
Operazioni analoghe sono possibili per i torrent. Si noti che non è possibile modificare un utente esistente; questo perché nel caso in cui i dati di un utente venissero modificati, non sarebbe possibile effettuare la validazione sui nuovi dati. E' evidente però che lo stesso risultato si ottiene cancellando l'utente esistente e creandone uno nuovo.

\chapter{Installazione e Deployment}
\label{ch:inst}
In questo capitolo viene presentato come effettuare l'installazione e il deployment dell'applicazione. Come accennato precedentemente, l'installazione dell'applicazione è stata fatta su cloud, in particolare su un server EC2 di Amazon. I requisiti necessari perché l'applicazione funzioni sono i seguenti:

\begin{description}
	\item[S.O. POSIX-compliant] l'applicazione è stata sviluppata e testata su diverse distribuzioni di GNU/Linux, ma dovrebbe poter essere installata e lanciata senza problemi anche su sistemi come Mac OS X, BSD, ecc.
	\item[Ruby] >=1.8.7, il linguaggio con cui è stata sviluppata l'applicazione;
	\item[RubyGems] ``package manager'' per Ruby, gesisce l'installazione dei componenti aggiuntivi necessari per far funzionare l'applicazione;
	\item[Rails] >=3.0.7, framework e stack applicativo con cui è stata sviluppata l'applicazione;
	\item[client Subversion] necessario per scaricare il codice sorgente dell'applicazione dal server google code;
	\item[MySQL] database server scelto per l'applicazione;
	\item[Transmission] client torrent necessario all'applicazione per gestire lo scaricamento dei file;
\end{description}

Poiché l'applicazione è stata sviluppata sulla distribuzione Debian di GNU/Linux, si è scelto di effettuare l'installazione sullo stesso sistema operativo. L'AMI (i.e. l'immagine della macchina Amazon) scelta pertanto è stata \textit{ami-0ce41865}, ovvero un'installazione base di Debian 6. Naturalmente è possibile installare l'applicazione su qualsiasi piattaforma che supporti i componenti necessari precedentemente elencati, ma le istruzioni qui riportate si riferiranno alla configurazione scelta.

Come prima cosa è necessario creare un istanza della macchina: dopo essersi registrati ed aver fatto il login nella console web di Amazon (\url{https://console.aws.amazon.com/}), scegliere dal tab \textit{EC2} di creare una nuova istanza (bottone \textit{Launch Istance}), e qui selezionare l'AMI ami-0ce41865; lasciare le impostazioni di default ma, prima di avviare la macchina, modificare le dimensioni dello storage: l'AMI è configurata con uno storage di un solo GB, che naturalmente è insufficiente. Questo può essere fatto dalla sezione \textit{Elastic Block Store} della web console di amazon \ref{fig:EBS}. Come prima cosa ``scollegare'' il volume dalla macchina (i.e. mouse di destra sul volume, \textit{Detach Volume}); creare uno snapshot del volume, ovvero salvare un immagine dei dati contenuti sullo storage che poi verranno caricati sul nuovo volume più grande: cliccando col mouse di destra sul volume, premere su \textit{Create Snapshot}, dare un nome allo snapshot. Una volta che lo snapshot è stato creato (lo stato può essere consultato nella sezione \textit{Snapshots}), creare un nuovo volume, di dimensioni maggiori (quanto meno 5GB per testare l'applicazione) selezionando lo snapshot appena creato. Infine ``ricollegare'' il volume alla macchina (i.e. mouse di destra sul nuovo volume, \textit{Attach Volume}, partizione \textit{/dev/sda1}). A questo punto è possibile avviare la macchina. 
\begin{figure}
\centering
\caption{Amazon web services console raffigurante i volumi correntemente posseduti.}
\label{fig:EBS}
\includegraphics[width = 0.9\textwidth]{../figures/EBS.png}
\end{figure} 

Una volta che la macchina si sarà avviata, è necessario connettersi per modificarne le impostazioni ed installare il software necessario. Cliccando col mouse di destra sull'istanza e premendo su \textit{Connect} compariranno delle istruzioni su come stabilire una connessione SSH con la macchina (figura \ref{fig:connect}). 

\begin{figure}
\centering
\caption{Amazon web services console raffigurante le istruzioni per connettersi all'istanza appena creata.}
\label{fig:connect}
\includegraphics[width = 0.9\textwidth]{../figures/connect.png}
\end{figure}

Una volta connessi alla macchina, come prima cosa vanno installati i tool necessari:
\begin{verbatim}
apt-get update
apt-get install gcc make subversion ruby1.8 ruby1.8-dev \
    transmission transmission-daemon mysql-client-5.1 \ 
	mysql-server-5.1  libmysqlclient-dev libmysql-ruby1.8 \
	sqlite3  libsqlite3-dev libsqlite3-ruby
wget http://rubyforge.org/frs/download.php/75255/rubygems-1.8.8.tgz
tar -xvvf rubygems-1.8.8.tgz
cd rubygems-1.8.8
ruby1.8 setup.rb
gem1.8 install --no-ri --no-rdoc rails
\end{verbatim}
A questo punto si dovrebbe avere un environment Ruby on Rails, un client Subversion e il database server MySQL funzionanti. Nel setup di MySQL scegliere la root password che si desidera. SQLite3 viene installato solo perché viene usato nell'ambiente di testing; nonostante questo ambiente non venga utilizzato nell'installazione dell'applicazione, SQLite3 è comunque inserito nelle dipendenze del progetto. A questo punto è necessario creare la cartella in cui viene scaricata l'applicazione e fare il checkout dal repository SVN. Questo può essere fatto digitando i seguenti comandi:
\begin{verbatim}
mkdir -pv /var/rails/
cd /var/rails/
svn checkout http://torrent-dam-2.googlecode.com/svn/trunk torrent_dam
cd torrent_dam
bundle install
\end{verbatim}
Se il comando \textit{bundle install} va a buon fine, tutto il progetto e i suoi componenti aggiuntivi sono stati installati. I componenti aggiuntivi installati possono essere consultati nel file \textit{Gemfile}. A questo punto l'applicazione è installata, va configurata e successivamente avviata. La prima cosa da fare è impostare la password che si è scelta per il database MySQL. Questo può essere fatto modificando la chiave password nella sezione development del file config/database.yml. A questo punto, dare i seguenti comandi: 

\begin{verbatim}
bundle exec rake db:create
bundle exec rake db:migrate
bundle exec rake db:seed
\end{verbatim}

Questi tre comandi sono necessari per creare il database relativo all'applicazione, creare le tabelle e riempirle con il primo utente, l'amministratore dell'applicazione. Infine, terminare il demone di transmission e riavviarlo e lanciare il webserver:

\begin{verbatim}
kill -9 `ps aux | grep transmission-daemon | head -1 \
    cut -d" " -f1`
transmission-daemon
rails s -p80 -d
\end{verbatim}
L'applicazione ora dovrebbe essere avviata ed e' possibile testarla connettendosi al server EC2 con il proprio browser. Il nome di dominio del server pu\'o essere letto nel tab Instances della console web di Amazon.
\end{document}
